<template>
    <div>
        <div style="margin-bottom:12px;display:flex;gap:12px;align-items:center;flex-wrap:wrap;">
            <label>题型：
                <select v-model="questionType" style="margin-right:8px;">
                    <option value="主观题">主观题</option>
                    <option value="客观题">客观题</option>
                </select>
            </label>
            <label>学科：
                <select v-model="subject" style="margin-right:8px;">
                    <option value="数学">数学</option>
                    <option value="语文">语文</option>
                    <option value="英语">英语</option>
                    <option value="物理">物理</option>
                    <option value="化学">化学</option>
                    <option value="生物">生物</option>
                    <option value="历史">历史</option>
                    <option value="地理">地理</option>
                </select>
            </label>
        </div>
        <div style="margin-bottom:12px;">
            各科评分标准：
            <div v-for="(item,index) in subjectScoreTips" :key="index">
               {{ index }}:{{ item }}
            </div>
        </div>
        <h1>题目原始数据</h1>
        <textarea v-model="inputHtml" rows="10" style="width:100%;margin-bottom:12px"
            placeholder="请粘贴带HTML标签的题目内容"></textarea>
        <h1>题目参考答案</h1>
        <textarea v-model="referenceAnswer" rows="3" style="width:100%;margin-bottom:12px"
            placeholder="请粘贴题目参考答案"></textarea>
        <h1>题目总分</h1>
        <input v-model="totalScore" type="number" min="0"
            style="width:200px;margin-bottom:12px;display:block;padding:6px 8px;border-radius:4px;border:1px solid #ccc;"
            placeholder="请输入题目总分" />
        <template v-if="questionType === '主观题'">
            <h1>学生作答图片地址</h1>
            <input v-model="studentImageUrl" type="text"
                style="width:100%;margin-bottom:12px;display:block;padding:6px 8px;border-radius:4px;border:1px solid #ccc;"
                placeholder="请输入学生作答图片地址" />
            <h1>预览学生作答图片</h1>
            <img :src="studentImageUrl" alt="学生作答图片" style="margin-bottom:12px" />
        </template>
        <template v-else>
            <h1>学生作答文本</h1>
            <input v-model="studentAnswerText" type="text"
                style="width:100%;margin-bottom:12px;display:block;padding:6px 8px;border-radius:4px;border:1px solid #ccc;"
                placeholder="请输入学生作答文本" />
        </template>

        <button @click="handleExecute" style="margin-bottom:12px">点击发送请求</button>
        <h3>结构化大模型入参：</h3>
        <textarea :value="resultJson" readonly rows="30"
            style="width:100%;background:#f8f8f8;padding:8px;border-radius:4px;margin-bottom:12px"></textarea>
        <h3>大模型返回结果：</h3>
        <textarea :value="llmResult" readonly rows="30"
            style="width:100%;background:#f8f8f8;padding:8px;border-radius:4px"></textarea>
    </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';
import _ from 'lodash-es';
const inputHtml = ref(`计算：<br />（1）如图圆柱的表面积．（π取3.14）<br /><img alt="菁优网" src="http://img.jyeoo.net/quiz/images/svg/202506/484/63a0febb.png" style="vertical-align:middle" /><br />（2）如图图形旋转一周后形成图形的体积．（π取3.14）<br /><img alt="菁优网" src="http://img.jyeoo.net/quiz/images/svg/202506/484/72e5d271.png" style="vertical-align:middle" />
`);
const referenceAnswer = ref('3');
const totalScore = ref('10');
const questionType = ref('主观题');
const subject = ref('数学');
const studentAnswerText = ref('');
const subjectScoreTips: Record<string, string> = {
    数学: '请关注解题步骤、计算过程、答案的正确性。若有步骤错误或漏写，适当扣分。评语需指出具体扣分点。',
    语文: '请关注答题内容的完整性、表达的准确性、书写规范。评语需指出表达优缺点。',
    英语: '请关注语法、词汇、句型和表达的准确性。评语需指出语法或表达问题。',
    物理: '请关注答题思路、实验步骤、公式、单位和答案的科学性。评语需指出科学性或步骤问题。',
    化学: '请关注答题思路、实验步骤、公式、单位和答案的科学性。评语需指出科学性或步骤问题。',
    生物: '请关注答题思路、实验步骤、科学性和表达完整性。评语需指出科学性或步骤问题。',
    历史: '请关注史实的准确性、逻辑性和表达完整性。评语需指出史实错误或表达不清。',
    地理: '请关注地理事实的准确性、逻辑性和表达完整性。评语需指出事实错误或表达不清。'
};
const studentImageUrl = ref('http://120.48.56.18:9000/public/521634973787096064/9277869022d65a8c2f95e6a05.png');
const resultJson = ref('');
const llmResult = ref('');

async function callLLMApi(question: any, referenceAnswer: string) {
    const apiUrl = 'https://ark.cn-beijing.volces.com/api/v3/chat/completions';

    const payload = {
        model: "doubao-seed-1-6-thinking-250715",
        messages: [
            {
                role: "user",
                content: question
            }
        ]
    };
    const headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer 72dc2959-814f-4fff-99b5-7bb49d67ab4f"
    };
    const response = await axios.post(apiUrl, payload, { headers });
    return response.data;
}

async function handleExecute() {
    const jsonArr = parseHtmlToBlocks(inputHtml.value);
    resultJson.value = JSON.stringify(jsonArr, null, 2);
    llmResult.value = '处理中...';
    try {
        const data = await callLLMApi(_.cloneDeep(jsonArr), referenceAnswer.value);
        console.log(data);
        llmResult.value = data.choices[0].message.content
    } catch (e: any) {
        llmResult.value = '请求失败：' + (e?.message || e);
    }
}

function extractBackgroundImages(html: string) {
  const urls: string[] = [];
  // 匹配 style="...background...url('...')..."
  const styleUrlRegex = /style\s*=\s*(["'])[^"']*url\((['"]?)(.*?)\2\)/gi;
  let match;
  while ((match = styleUrlRegex.exec(html)) !== null) {
    const url = match[3];
    if (url && (url.startsWith('http://') || url.startsWith('https://'))) {
      urls.push(url);
    }
  }
  return urls;
}

/**
 * 将一段原始 HTML 字符串解析为结构化图文混排数组
 * @param {string} htmlString 原始 HTML 字符串
 * @returns {Array} 结构化数组
 */
function parseHtmlToBlocks(htmlString: string) {
  const blocks: any[] = [];
  const container = document.createElement('div');
  container.innerHTML = htmlString;

  function walk(node: Node) {
    if (node.nodeType === 1) {
      const el = node as HTMLElement;
      // 处理 <img>
      if (el.tagName === 'IMG') {
        const src = el.getAttribute('src');
        if (src && (src.startsWith('http://') || src.startsWith('https://'))) {
          blocks.push({ type: 'image_url', image_url: src });
        }
      }
      // 处理 background-image
      const style = el.getAttribute('style') || '';
      const bgUrlMatch = style.match(/url\(['"]?(.*?)['"]?\)/i);
      if (bgUrlMatch && (bgUrlMatch[1].startsWith('http://') || bgUrlMatch[1].startsWith('https://'))) {
        blocks.push({ type: 'image_url', image_url: bgUrlMatch[1] });
        // 不再把整个节点原样作为 text
        return;
      }
      // 递归处理子节点
      Array.from(el.childNodes).forEach(walk);
    } else if (node.nodeType === 3) {
      // 普通文本
      const text = node.textContent?.trim();
      if (text) {
        blocks.push({ type: 'text', text });
      }
    }
  }
  Array.from(container.childNodes).forEach(walk);
  // 题型、答案、总分等后续逻辑保持不变（如有）
  blocks.push({
    type: 'text',
    text: `题目类型：${questionType.value}\n学科：${subject.value}`
  });
  if (referenceAnswer.value) {
    blocks.push({ type: 'text', text: '参考答案：' + referenceAnswer.value });
  }
  if (totalScore.value) {
    blocks.push({ type: 'text', text: '题目总分：' + totalScore.value + '分' });
  }
  if (questionType.value === '主观题') {
    if (studentImageUrl.value) {
      blocks.push({ type: 'text', text: '学生作答图片如下：' });
      blocks.push({ type: 'image_url', image_url: { url: studentImageUrl.value } });
    }
    blocks.push({
      type: 'text',
      text: `请结合参考答案和评分标准，合理给分并说明理由。${subjectScoreTips[subject.value] || ''} 只输出如下 JSON 格式：{"score": 得分, "comment": "评语", "score_reason": "评分依据"}，不要输出其它内容。`
    });
  } else {
    if (studentAnswerText.value) {
      blocks.push({ type: 'text', text: '学生作答：' + studentAnswerText.value });
    }
    blocks.push({
      type: 'text',
      text: `请严格按照参考答案判分，完全一致才得分，否则不得分。${subjectScoreTips[subject.value] || ''} 只输出如下 JSON 格式：{"score": 得分, "is_correct": true/false, "student_answer": "...", "correct_answer": "...", "comment": "评语"}，不要输出其它内容。`
    });
  }
  return blocks;
}
</script>

<style scoped lang="scss">
textarea {
    font-family: inherit;
    font-size: 15px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 8px;
    margin-bottom: 8px;
}

button {
    padding: 6px 18px;
    background: #1976d2;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 15px;
    margin-bottom: 8px;
}

button:hover {
    background: #1565c0;
}
</style>